﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HandScreen.DataMining;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media.Animation;

namespace HandScreen.Views
{
    /// <summary>
    /// Interaction logic for ChalmersNewsView.xaml
    /// </summary>
    public partial class ChalmersNewsView : UserControl, IScrollable, ISuspendable
    {
        NewsData[] theNews;
        TextBlock[] theTextBlocks;
        const int nrOfReports = 10;
        const int updateInterval = 300000;
        private bool canScrollUp;
        private bool canScrollDown;
        private bool alive;
        private Thread updater;

        public ChalmersNewsView()
        {
            alive = true;
            InitializeComponent();
            theNews = new NewsData[nrOfReports];
            theTextBlocks = new TextBlock[nrOfReports * 3];
            updater = new Thread(dataMineChalmersNews);
            updater.Start();
        }

        private void dataMineChalmersNews()
        {
            Boolean first = true;
            while (alive)
            {
                if (first)
                {
                    first = false;
                    InitializeDataMiner();
                    this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
                        delegate()
                        {
                            AddTextBlocks();
                            Thread initialize = new Thread(initializeAfterData);
                            initialize.Start();
                        }
                    ));
                }
                else
                {
                    theNews = new NewsData[nrOfReports];
                    InitializeDataMiner();

                    this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
                        delegate()
                        {
                            UpdateGUI();
                        }
                    ));
                }
                try { Thread.Sleep(updateInterval); }
                catch (Exception e) { }
            }
        }

        private void initializeAfterData()
        {
            Thread.Sleep(500);
            this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
                    delegate()
                    {
                        scrollToPosition(scrollContainer.HorizontalOffset, scrollContainer.VerticalOffset);
                    }
                ));
        }

        public void UpdateGUI()
        {
            for (int i = 0; i < nrOfReports; i++)
            {
                theTextBlocks[i].Text = theNews[i].getTitle();
                theTextBlocks[nrOfReports + i].Text = theNews[i].getDate();
                theTextBlocks[nrOfReports*2 + i].Text = theNews[i].getDescription();
            }

        }

        private void AddTextBlocks()
        {
            for (int i = 0; i < nrOfReports; i++)
            {
                theTextBlocks[i] = new TextBlock();
                theTextBlocks[i].Text = theNews[i].getTitle();
                theTextBlocks[nrOfReports + i] = new TextBlock();
                theTextBlocks[nrOfReports + i].Text = theNews[i].getDate();
                theTextBlocks[nrOfReports*2 + i] = new TextBlock();
                theTextBlocks[nrOfReports*2 + i].Text = theNews[i].getDescription();

                theTextBlocks[i].FontSize = theTextBlocks[i].FontSize + 10;
                theTextBlocks[i].FontWeight = FontWeights.Heavy;
                theTextBlocks[nrOfReports + i].FontSize = theTextBlocks[i].FontSize - 7;
                theTextBlocks[nrOfReports*2 + i].FontSize = theTextBlocks[i].FontSize - 3;

                theTextBlocks[i].TextWrapping = TextWrapping.Wrap;
                theTextBlocks[i].Margin = new Thickness(10, 1, 10, 1);

                theTextBlocks[nrOfReports + i].TextWrapping = TextWrapping.Wrap;
                theTextBlocks[nrOfReports + i].Margin = new Thickness(10, 1, 10, 1);
                theTextBlocks[nrOfReports*2 + i].TextWrapping = TextWrapping.Wrap;
                theTextBlocks[nrOfReports*2 + i].Margin = new Thickness(10, 2, 10, 15);

                contentStack.Children.Add(theTextBlocks[i]);
                contentStack.Children.Add(theTextBlocks[nrOfReports + i]);
                contentStack.Children.Add(theTextBlocks[nrOfReports * 2 + i]);
            }

        }

        private void InitializeDataMiner()
        {
            RSSManager reader = new RSSManager();
            Collection<Rss.Items> list;

            String feed = "https://www.chalmers.se/insidan/feed?id=chalmers_insidan_main_news_en";

            reader.Url = feed;
            reader.GetRSSFeed();
            list = reader.RSSItems;

            try
            {
                int nrOfEntries = 0;
                if (list.Count >= nrOfReports)
                    nrOfEntries = nrOfReports;
                for (int i = 0; i < nrOfEntries; i++)
                {
                    String title = list[i].Title;
                    String date = list[i].Date.ToString();
                    String description = list[i].Description.ToString();
                    theNews[i] = new NewsData(title, date, description);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        public void scrollUp()
        {
            //scrollContainer.ScrollToVerticalOffset(scrollContainer.VerticalOffset - scrollContainer.ActualHeight * 0.80);
            scrollToPosition(scrollContainer.HorizontalOffset, scrollContainer.VerticalOffset - scrollContainer.ActualHeight * 0.80);
        }

        public void scrollDown()
        {
            //scrollContainer.ScrollToVerticalOffset(scrollContainer.VerticalOffset + scrollContainer.ActualHeight * 0.80);
            scrollToPosition(scrollContainer.HorizontalOffset, scrollContainer.VerticalOffset + scrollContainer.ActualHeight * 0.80);
        }

        private void scrollToPosition(double x, double y)
        {
            DoubleAnimation vertAnim = new DoubleAnimation();
            vertAnim.From = scrollContainer.VerticalOffset;
            vertAnim.To = y;
            vertAnim.DecelerationRatio = .2;
            vertAnim.Duration = new Duration(TimeSpan.FromMilliseconds(250));

            DoubleAnimation horzAnim = new DoubleAnimation();
            horzAnim.From = scrollContainer.HorizontalOffset;
            horzAnim.To = x;
            horzAnim.DecelerationRatio = .2;
            horzAnim.Duration = new Duration(TimeSpan.FromMilliseconds(300));

            Storyboard sb = new Storyboard();
            sb.Children.Add(vertAnim);
            sb.Children.Add(horzAnim);

            Storyboard.SetTarget(vertAnim, scrollContainer);
            Storyboard.SetTargetProperty(vertAnim, new PropertyPath(AniScrollViewer.CurrentVerticalOffsetProperty));
            Storyboard.SetTarget(horzAnim, scrollContainer);
            Storyboard.SetTargetProperty(horzAnim, new PropertyPath(AniScrollViewer.CurrentHorizontalOffsetProperty));

            sb.Begin();

            if (contentStack.ActualHeight - scrollContainer.ActualHeight <= 0)
            {
                topFade.Visibility = System.Windows.Visibility.Hidden;
                canScrollUp = false;
                bottomFade.Visibility = System.Windows.Visibility.Hidden;
                canScrollDown = false;
            }
            else
            {
                if (y <= 0)
                {
                    topFade.Visibility = System.Windows.Visibility.Hidden;
                    canScrollUp = false;
                }
                else
                {
                    topFade.Visibility = System.Windows.Visibility.Visible;
                    canScrollUp = true;
                }
                if (y >= contentStack.ActualHeight - scrollContainer.ActualHeight)
                {
                    bottomFade.Visibility = System.Windows.Visibility.Hidden;
                    canScrollDown = false;
                }
                else
                {
                    bottomFade.Visibility = System.Windows.Visibility.Visible;
                    canScrollDown = true;
                }
            }
        }

        public bool CanScrollUp()
        {
            return canScrollUp;
        }

        public bool CanScrollDown()
        {
            return canScrollDown;
        }

        public void suspend()
        {
            alive = false;
            updater.Interrupt();
        }
    }

    public class NewsData
    {
        String Title;
        String Date;
        String Description;

        public NewsData(String Title, String Date, String Description)
        {
            this.Title = Title;
            this.Date = Date;
            this.Description = Description;
        }
        public String getTitle()
        {
            return Title;
        }
        public String getDate()
        {
            return Date;
        }
        public String getDescription()
        {
            return Description;
        }
    }
}
